import { IApiItem } from '@/utils/interfaces'
import { mock } from '@/utils/mock'
import { store } from '@/utils/store/store'
import { getCurrentExpect, getVarContext } from '@/utils/variableHandlers'
import { camelCase } from 'lodash-es'
import { IRequest } from './interface'

// url匹配函数
export const urlMatchHandlers: {
    [key in NonNullable<IApiItem['machMode']>]: (
        reqUrl: string,
        apiUrl: string,
    ) => boolean
} = {
    includes: (reqUrl, apiUrl) => reqUrl.includes(apiUrl),
    equal: (reqUrl, apiUrl) => reqUrl === apiUrl,
    regex: (reqUrl, apiUrl) => new RegExp(apiUrl).test(reqUrl),
}

// 匹配
export const matchRequest = async (request: IRequest) => {
    const list = await store.get('list')
    if (!list?.length) {
        return
    }
    // 开始筛选
    const matchedItem = list.find((item) => {
        if (item.type !== 'api') {
            return false
        }
        if (item.type !== 'api' || !item?.enabled) {
            return false
        }
        const matcher = urlMatchHandlers[item?.machMode || 'includes']
        if (item?.url && matcher(request.url, item.url)) {
            // 往上检查item的父级，如果某个父级未启用则返回false
            let parentId = item.parentId
            while (parentId) {
                const parent = list.find((i) => i.id === parentId)
                if (!parent || !parent?.enabled) {
                    return false
                }
                parentId = parent.parentId
            }
            return true
        }
    })
    return matchedItem as IApiItem | undefined
}

// 获取mock后的结果
export const getMockResult = async (apiItem: IApiItem, req?: IRequest) => {
    // 获取选中的期望
    const expect = getCurrentExpect(apiItem)
    // 找到期望
    if (!expect) {
        return
    }
    // 获取handlers和variables
    let { handlers, variables } = expect

    // 获取启用的handlers
    let enabledHandlers = Object.keys(handlers || {}).filter(
        (key) => handlers?.[key as IApiHandlerIds]?.enabled,
    )
    // 如果当前期望没有启用的handlers，则尝试使用默认期望的handlers
    if (!enabledHandlers.length) {
        enabledHandlers = Object.keys(apiItem?.handlers || {}).filter(
            (key) => apiItem?.handlers?.[key as IApiHandlerIds]?.enabled,
        )
        handlers = apiItem?.handlers || {}
    }
    // 还是没有就返回
    if (!enabledHandlers.length) {
        return
    }

    // 处理variables
    let varContext: Record<string, any> = {
        ...defualtReqContextVars,
        ...getVarContext(variables),
    }

    // 加上reqUrl,reqMethod,reqBody,reqHeaders
    if (req) {
        Object.keys(req).forEach((key) => {
            const newKey = `req-${key}`
            const camelCased = camelCase(newKey)
            let value = req[key as keyof IRequest]
            if (typeof value === 'string') {
                try {
                    value = JSON.parse(value)
                } catch {}
            }
            varContext![camelCased] = value
        })
    }

    // 处理handlers
    const result: {
        [key in IApiHandlerIds]?: any
    } = {}
    enabledHandlers.forEach((k) => {
        const key = k as IApiHandlerIds
        const handler = handlers?.[key]
        if (!handler) {
            return
        }
        const mockRule = handler.mockRule
        if (!mockRule) {
            return
        }
        result[key] = mock(mockRule, {
            varContext,
        })
    })
    return result
}
